﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using XMK.Framework.Model;
using System.Data.Common;
using XMK.Utils;


namespace XMK.Framework.DataAccess
{
    /// <summary>
    /// 数据库管理类
    /// </summary>
    public sealed class DbManager
    {
        #region 获取列表
        /// <summary>
        /// 分页对象列表的取得
        /// </summary>
        /// <typeparam name="T">返回对象类型</typeparam>
        /// <param name="sqlInfo">SQL命令实例</param>
        /// <param name="pageInfo">分页信息</param>
        /// <param name="fun">转换方法</param>
        /// <returns>对象类型的分页列表</returns>
        public static List<T> GetPageInfos<T>(DbCmdHelper sqlInfo, PageInfo pageInfo, DataRowFullInfoFun<T> fun) where T : new()
        {
            // 取得数据
            DataTable ds = DbHelper.ExecFullDataTable(sqlInfo.DbProvider, sqlInfo.DbCmdInfo);
            // 取得分页数据
            sqlInfo.GetReturnPageInfo(pageInfo);
            List<T> list = DataTableFullInfos<T>(ds, fun);
            pageInfo.CurrentRecords = list.Count;
            return list;
        }
        /// <summary>
        /// 对象列表的取得
        /// </summary>
        /// <typeparam name="T">返回对象类型</typeparam>
        /// <param name="sqlInfo">SQL命令实例</param>
        /// <param name="fun">转换方法</param>
        /// <returns>对象类型的列表</returns>
        public static List<T> GetInfoList<T>(DbCmdHelper sqlInfo, DataRowFullInfoFun<T> fun) where T : new()
        {
            DataTable dt = DbHelper.ExecFullDataTable(sqlInfo.DbProvider, sqlInfo.DbCmdInfo);
            return DataTableFullInfos<T>(dt, fun);
        }

        /// <summary>
        /// 返回数据表
        /// </summary>
        /// <param name="sqlInfo"></param>
        /// <returns></returns>
        public static DataTable ExecuteDataTable(DbCmdHelper sqlInfo)
        {
            return DbHelper.ExecFullDataTable(sqlInfo.DbProvider, sqlInfo.DbCmdInfo);
        }

        /// <summary>
        /// 返回分页数据表
        /// </summary>
        /// <param name="sqlInfo"></param>
        /// <param name="pageInfo"></param>
        /// <returns></returns>
        public static DataTable ExecutePageDataTable(DbCmdHelper sqlInfo, PageInfo pageInfo)
        {
            // 取得数据
            DataTable ds = DbHelper.ExecFullDataTable(sqlInfo.DbProvider, sqlInfo.DbCmdInfo);
            // 取得分页数据
            sqlInfo.GetReturnPageInfo(pageInfo);
            pageInfo.CurrentRecords = ds.Rows.Count;
            return ds;
        }

        /// <summary>
        /// 对象列表（列表需从后面表进行填充）的取得
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sqlInfo"></param>
        /// <param name="fun"></param>
        /// <returns></returns>
        public static List<T> GetInfoList<T>(DbCmdHelper sqlInfo, DataRowFullInfoHaveListFun<T> fun) where T : new()
        {
            DataSet ds = DbHelper.ExecFullDataSet(sqlInfo.DbProvider, sqlInfo.DbCmdInfo);
            return DataTableFullInfos<T>(ds, fun);
        }
        private static List<T> DataTableFullInfos<T>(DataSet dataSet, DataRowFullInfoHaveListFun<T> fun) where T : new()
        {
            List<T> list = new List<T>();
            T t;
            foreach (DataRow dr in dataSet.Tables[0].Rows)
            {
                fun(out t, dr, dataSet);
                list.Add(t);
            }
            return list;
        }
        /// <summary>
        /// 数据转换为对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="dataTable">数据</param>
        /// <param name="fun">转换方法</param>
        /// <returns>对象类型的列表</returns>
        public static List<T> DataTableFullInfos<T>(DataTable dataTable, DataRowFullInfoFun<T> fun) where T : new()
        {
            List<T> list = new List<T>();
            T t;
            foreach (DataRow dr in dataTable.Rows)
            {
                fun(out t, dr);
                list.Add(t);
            }
            return list;
        }
        /// <summary>
        /// 根据数据库缓存依赖取得数据
        /// </summary>
        /// <typeparam name="T">返回对象类型</typeparam>
        /// <param name="sqlCmdHelper">数据库操作帮助类</param>
        /// <param name="fun">对象的填充委托</param>
        /// <returns>对象列表</returns>
        public static List<T> GetCacheInfoList<T>(DbCmdHelper sqlCmdHelper, DataRowFullInfoFun<T> fun) where T : new()
        {
            DbDependency<T> dep = sqlCmdHelper.DbProvider.CreateDbDependency<T>(sqlCmdHelper.DbCmdInfo.SqlText, fun);
            return dep.GetCacheData();
        }
        #endregion

        #region 单个操作
        /// <summary>
        /// 获取单个对象
        /// </summary>
        /// <typeparam name="T">返回对象类型</typeparam>
        /// <param name="sqlCmdHelper">SQL命令实例</param>
        /// <param name="fun">转换方法</param>
        /// <returns>对象详情</returns>
        public static T GetInfo<T>(DbCmdHelper sqlCmdHelper, DataRowFullInfoFun<T> fun) where T : new()
        {
            // 取得数据
            DataTable dt = DbHelper.ExecFullDataTable(sqlCmdHelper.DbProvider, sqlCmdHelper.DbCmdInfo);
            if (dt == null || dt.Rows.Count < 1)
                return default(T);
            T t = new T();
            fun(out t, dt.Rows[0]);
            return t;
        }

        /// <summary>
        /// 取得对象(有List的属性)详细
        /// </summary>
        /// <typeparam name="T">返回对象类型</typeparam>
        /// <param name="sqlCmdHelper">SQL命令实例</param>
        /// <param name="fun">转换方法</param>
        /// <returns>对象(有List的属性)详细</returns>
        public static T GetInfo<T>(DbCmdHelper sqlCmdHelper, DataRowFullInfoHaveListFun<T> fun) where T : new()
        {
            // 取得数据
            DataSet ds = DbHelper.ExecFullDataSet(sqlCmdHelper.DbProvider, sqlCmdHelper.DbCmdInfo);
            if (ds == null || ds.Tables.Count < 1 || ds.Tables[0].Rows.Count < 1)
                return default(T);
            T t = new T();
            fun(out t, ds.Tables[0].Rows[0], ds);
            return t;
        }
        /// <summary>
        /// 执行命令并返回返回受影响的行数
        /// </summary>
        /// <param name="sqlCmdHelper">数据库操作帮助类</param>
        /// <returns>数据库操作影响的行数</returns>
        public static int ExecNonQuery(DbCmdHelper sqlCmdHelper)
        {
            return DbHelper.ExecNonQuery(sqlCmdHelper.DbProvider, sqlCmdHelper.DbCmdInfo);
        }
        /// <summary>
        /// 执行命令并返回查询所返回的结果集中第一行的第一列
        /// </summary>
        /// <param name="sqlCmdHelper">数据库操作帮助类</param>
        /// <returns>结果集中第一行的第一列</returns>
        public static object ExecScalar(DbCmdHelper sqlCmdHelper)
        {
            return DbHelper.ExecScalar(sqlCmdHelper.DbProvider, sqlCmdHelper.DbCmdInfo);
        }
        #endregion

        #region 执行事务
        /// <summary>
        /// 执行事务
        /// </summary>
        /// <param name="dbProvider">数据库驱动</param>
        /// <param name="dbCmdInfos">数据库命令列表</param>
        /// <returns>是否执行成功</returns>
        public static bool ExecTrans(DbProvider dbProvider, params DbCmdInfo[] dbCmdInfos)
        {
            return DbHelper.ExecTrans(dbProvider, dbCmdInfos);
        }
        /// <summary>
        /// 执行事务并每次调用数据库操作后调用委托
        /// </summary>
        /// <param name="dbProvider">数据库驱动</param>
        /// <param name="transSqlCmdFun">数据库操作后调用委托</param>
        /// <param name="dbCmdInfos">数据库命令列表</param>
        /// <returns>是否执行成功</returns>
        public static bool ExecTrans(DbProvider dbProvider, TransDbCmdFun transSqlCmdFun, params DbCmdInfo[] dbCmdInfos)
        {
            return DbHelper.ExecTrans(dbProvider, dbCmdInfos, transSqlCmdFun);
        }
        #endregion

        #region 执行多个命令
        /// <summary>
        /// 执行事务
        /// </summary>
        /// <param name="dbProvider">数据库驱动</param>
        /// <param name="dbCmdInfos">数据库命令列表</param>
        /// <returns>是否执行成功</returns>
        public static bool ExecDbCmdInfos(DbProvider dbProvider, params DbCmdInfo[] dbCmdInfos)
        {
            return DbHelper.ExecDbCmdInfos(dbProvider, dbCmdInfos);
        }
        /// <summary>
        /// 执行事务并每次调用数据库操作后调用委托
        /// </summary>
        /// <param name="dbProvider">数据库驱动</param>
        /// <param name="transSqlCmdFun">数据库操作后调用委托</param>
        /// <param name="dbCmdInfos">数据库命令列表</param>
        /// <returns>是否执行成功</returns>
        public static bool ExecDbCmdInfos(DbProvider dbProvider, TransDbCmdFun transSqlCmdFun, params DbCmdInfo[] dbCmdInfos)
        {
            return DbHelper.ExecDbCmdInfos(dbProvider, dbCmdInfos, transSqlCmdFun);
        }
        #endregion
    }
}
